package com.xms.web.framework.filter;

import com.xms.core.annotation.AllowAnonymous;
import com.xms.core.org.UserContext;
import com.xms.security.identity.IAuthenticationService;
import com.xms.security.identity.ICurrentUser;
import com.xms.security.service.IPrivilegeFilterService;
import com.xms.utils.JsonUtil;
import com.xms.utils.StringUtil;
import com.xms.web.framework.model.JsonResultObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * <p>
 * 权限验证拦截器
 * </p>
 *
 * @author migo
 * @since 2021/9/11
 */
@Component
public class AuthorizedInterceptor implements HandlerInterceptor {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private IPrivilegeFilterService _privilegeFilterService;
    private IAuthenticationService _authenticationService;
    private ICurrentUser _currentUser;

    @Autowired
    public void AuthorizedInterceptor(IPrivilegeFilterService privilegeFilterService,
                                      IAuthenticationService authenticationService,
                                      ICurrentUser currentUser) {
        _privilegeFilterService = privilegeFilterService;
        _authenticationService = authenticationService;
        _currentUser = currentUser;
    }

    @Override
    public boolean preHandle(HttpServletRequest httpRequest, HttpServletResponse httpResponse, Object o) throws Exception {
        if(!(o instanceof HandlerMethod)){
            return true;
        }
        boolean allowAnnoymous = ((HandlerMethod) o).getBean().getClass().isAnnotationPresent(AllowAnonymous.class);
        if(!allowAnnoymous){
            allowAnnoymous = ((HandlerMethod) o).getMethod().isAnnotationPresent(AllowAnonymous.class);
        }
        if(allowAnnoymous){
            return true;
        }
        boolean hasPermission = false;
        UserContext user =  _currentUser.getUser();
        String path = httpRequest.getRequestURI();
        if(!_authenticationService.isAuthenticated(httpRequest) || user == null){
            hasPermission = false;
        }
        else {
            //获取控制器的名字
            //String controllerName = ((HandlerMethod) o).getBean().getClass().getSimpleName();
            //获取方法名
            //String actionName = ((HandlerMethod) o).getMethod().getName();
            //替换组织路径前缀
            path = path.replace("/" + _currentUser.getUser().OrganizationUniqueName, "");
            if (StringUtil.isEmpty(path) || path.equalsIgnoreCase("/")) {
                return true;
            }
            hasPermission = _privilegeFilterService.hasPermission(_currentUser, path, true);
        }
        if(!hasPermission){
            if(path.indexOf("/api") >= 0){
                writeJson(httpResponse, JsonUtil.toJSONString(JsonResultObject.failure("unauthorized", 401)));
            }
            else {
                //httpRequest.getRequestDispatcher("/unauthorized").forward(servletRequest, servletResponse);
                httpResponse.sendRedirect("/unauthorized");
            }
            return false;
        }

        return true;
    }


    private void writeJson(HttpServletResponse response, String json) {
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(json);

        } catch (IOException e) {
            logger.error("response error", e);
        } finally {
            if (writer != null)
                writer.close();
        }
    }
}
